/*
 * Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
#include <nv.h>
#include <errcode.h>
#include "kh_device_info.h"


#define SN_LEN (18+1)
#define SN_KEY (NV_ID_USER_STABLE_AREA_START + 1)


static char g_deviceSN[SN_LEN] = {0};

int setDeviceSN(const char *sn)
{
    if (sn == NULL) {
        return -1;
    }
    nv_key_attr_t nv_attr = {0};
    uint8_t sn_key_value[SN_LEN] = {0};
    size_t length;
    length = strlen(sn) + 1;

    if (length != SN_LEN){
        return -1;
    }

    nv_attr.permanent = false;
    nv_attr.encrypted = false;
    nv_attr.non_upgrade = false;
    memcpy(sn_key_value, sn, length);

    int32_t ret = uapi_nv_write_with_attr(SN_KEY, sn_key_value, length, &nv_attr, NULL);
    if (ret != ERRCODE_SUCC) {
        printf("setDeviceSN failed, ret = [0x%x]\r\n", ret);
        return ret;
    }

    return ERRCODE_SUCC;
}

const char *getDeviceSN(void)
{
    uint32_t ret = ERRCODE_FAIL;
    uint8_t sn_key_value[SN_LEN] = {0};
    uint16_t nv_key_length = 0;
    unsigned int random_sn = 1234;
    char sn_rand_value[SN_LEN] = {0};

    ret = uapi_nv_read(SN_KEY, SN_LEN, &nv_key_length,
        sn_key_value);

    if (ret != ERRCODE_SUCC) {
        printf("getDeviceSN failed, ret = [0x%x], sn_key_value = %s\r\n", ret, sn_key_value);
        random_sn = rand()%10000;
        sprintf((char*)sn_rand_value, "00000000000000%04u", (unsigned int)random_sn);
        memcpy((void *)g_deviceSN, (const void *)sn_rand_value, SN_LEN);  // NOLINT
        g_deviceSN[0] = 'R';

        printf("getDeviceSN random gen g_deviceSN = %s\r\n", g_deviceSN);

        setDeviceSN(g_deviceSN);
        //return NULL;
    }

    memcpy((void *)g_deviceSN, (const void *)sn_key_value, nv_key_length);

    return g_deviceSN;
}

const char *HalGetSerial(void)
{
    return getDeviceSN();
}